package cn.cjxy.springboot_zonghe_practice.service.impl;

import cn.cjxy.springboot_zonghe_practice.domain.Dept;
import cn.cjxy.springboot_zonghe_practice.domain.OperationLog;
import cn.cjxy.springboot_zonghe_practice.mapper.DeptMapper;
import cn.cjxy.springboot_zonghe_practice.mapper.EmpMapper;
import cn.cjxy.springboot_zonghe_practice.query.BaseQuery;
import cn.cjxy.springboot_zonghe_practice.service.DeptService;
import cn.cjxy.springboot_zonghe_practice.service.OperationLogService;
import cn.cjxy.springboot_zonghe_practice.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 部门服务实现类
 * 实现部门的增删改查、分页查询、批量操作等功能
 * 包含业务逻辑校验和操作日志记录
 * 
 * @author huangjie
 * @since 2025-07-06
 */
@Service
public class DeptServiceImpl implements DeptService {
    
    /**
     * 部门数据访问层
     */
    @Autowired
    private DeptMapper deptMapper;
    
    /**
     * 员工数据访问层，用于检查部门下是否有员工
     */
    @Autowired
    private EmpMapper empMapper;
    
    /**
     * 操作日志服务，用于记录所有操作
     */
    @Autowired
    private OperationLogService operationLogService;

    /**
     * 添加部门
     * 业务规则：
     * 1. 部门名称不能重复
     * 2. 一个员工只能当一个部门的经理
     * 
     * @param dept 部门信息对象
     * @return 操作结果
     */
    @Override
    public R addDept(Dept dept) {
        // 校验部门名称唯一性
        Integer i = deptMapper.selectDeptNameCount(dept.getDeptName());
        if(i != 0) {
            return R.fail("部门名称已存在!");
        }
        
        // 校验部门经理唯一性：一个员工只能做一个部门的经理
        if (dept.getDeptManagerId() != null) {
            Integer count = deptMapper.selectDeptManagerIdCount(dept.getDeptManagerId());
            if(count != 0){
                return R.fail("该员工已是部门经理");
            }
        }
        
        // 执行添加操作
        deptMapper.addDept(dept);
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("添加");
        log.setObjectType("部门");
        log.setObjectId(dept.getId());
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("添加部门:" + dept.getDeptName());
        operationLogService.log(log);
        
        return R.ok();
    }

    /**
     * 修改部门信息
     * 业务规则：
     * 1. 部门名称不能与其他部门重复（排除自己）
     * 2. 一个员工只能当一个部门的经理（排除自己）
     * 
     * @param dept 部门信息对象（必须包含id）
     * @return 操作结果
     */
    @Override
    public R updateDept(Dept dept) {
        // 校验部门名称唯一性（排除当前部门）
        Integer i = deptMapper.selectDeptNameAndNotIdCount(dept.getDeptName(), dept.getId());
        if(i != 0){
            return R.fail("部门名称已存在!");
        }
        
        // 校验部门经理唯一性（排除当前部门）
        if (dept.getDeptManagerId() != null) {
            Integer i1 = deptMapper.selectDeptManagerIdAndNotIdCount(dept.getDeptManagerId(), dept.getId());
            if(i1 != 0){
                return R.fail("该员工已是部门经理");
            }
        }
        
        // 执行修改操作
        deptMapper.updateDept(dept);
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("修改");
        log.setObjectType("部门");
        log.setObjectId(dept.getId());
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("修改部门:" + dept.getDeptName());
        operationLogService.log(log);
        
        return R.ok();
    }

    /**
     * 根据ID删除部门
     * 业务规则：只有没有员工的部门才能被删除
     * 
     * @param id 部门ID
     * @return 操作结果
     */
    @Override
    public R delDeptById(Long id) {
        // 检查部门下是否有员工，有员工的部门不能删除
        Integer empCount = empMapper.selectEmpByDeptId(id);
        if (empCount > 0) {
            return R.fail("该部门下有员工，不能删除!");
        }
        
        // 执行删除操作
        deptMapper.delDeptById(id);
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("删除");
        log.setObjectType("部门");
        log.setObjectId(id);
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("删除部门ID:" + id);
        operationLogService.log(log);
        
        return R.ok();
    }

    /**
     * 根据ID查询部门信息
     * 
     * @param id 部门ID
     * @return 查询结果，包含部门详细信息
     */
    @Override
    public R selectById(Long id) {
        Dept dept = deptMapper.selectById(id);
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("查询");
        log.setObjectType("部门");
        log.setObjectId(id);
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("查询部门ID:" + id);
        operationLogService.log(log);
        
        return R.ok(dept);
    }

    /**
     * 查询所有部门
     * 
     * @return 所有部门列表
     */
    @Override
    public R selectAll() {
        List<Dept> depts = deptMapper.selectAll();
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("查询");
        log.setObjectType("部门");
        log.setObjectId(null);
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("查询所有部门");
        operationLogService.log(log);
        
        return R.ok(depts);
    }
    
    /**
     * 分页查询部门
     * 
     * @param query 分页查询参数，包含页码和每页大小
     * @return 分页结果，包含部门列表、总数、当前页码、每页大小
     */
    @Override
    public R selectDeptByPage(BaseQuery query) {
        // 执行分页查询
        List<Dept> depts = deptMapper.selectDeptByPage(query.getStart(), query.getPageSize());
        Integer total = deptMapper.selectDeptCount();
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", depts);
        result.put("total", total);
        result.put("currentPage", query.getCurrentPage());
        result.put("pageSize", query.getPageSize());
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("查询");
        log.setObjectType("部门");
        log.setObjectId(null);
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("分页查询部门，页码:" + query.getCurrentPage() + "，每页大小:" + query.getPageSize());
        operationLogService.log(log);
        
        return R.ok(result);
    }
    
    /**
     * 批量添加部门
     * 业务规则：
     * 1. 部门名称不能重复
     * 2. 一个员工只能当一个部门的经理
     * 
     * @param depts 部门列表
     * @return 操作结果
     */
    @Override
    public R batchAddDept(List<Dept> depts) {
        // 批量校验部门名唯一性
        for (Dept dept : depts) {
            Integer count = deptMapper.selectDeptNameCount(dept.getDeptName());
            if (count > 0) {
                return R.fail("部门名称 " + dept.getDeptName() + " 已存在!");
            }
            
            // 检查部门经理唯一性
            if (dept.getDeptManagerId() != null) {
                Integer managerCount = deptMapper.selectDeptManagerIdCount(dept.getDeptManagerId());
                if (managerCount > 0) {
                    return R.fail("员工ID " + dept.getDeptManagerId() + " 已是部门经理!");
                }
            }
        }
        
        // 执行批量添加操作
        deptMapper.batchAddDept(depts);
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("批量添加");
        log.setObjectType("部门");
        log.setObjectId(null);
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("批量添加部门，数量:" + depts.size());
        operationLogService.log(log);
        
        return R.ok();
    }
    
    /**
     * 批量删除部门
     * 业务规则：只有没有员工的部门才能被删除
     * 
     * @param ids 部门ID列表
     * @return 操作结果
     */
    @Override
    public R batchDeleteDept(List<Long> ids) {
        // 检查是否有部门下有员工
        for (Long id : ids) {
            Integer empCount = empMapper.selectEmpByDeptId(id);
            if (empCount > 0) {
                Dept dept = deptMapper.selectById(id);
                return R.fail("部门 " + dept.getDeptName() + " 下有员工，不能删除!");
            }
        }
        
        // 执行批量删除操作
        deptMapper.batchDeleteDept(ids);
        
        // 记录操作日志
        OperationLog log = new OperationLog();
        log.setOperationType("批量删除");
        log.setObjectType("部门");
        log.setObjectId(null);
        log.setOperator("system");
        log.setOperationTime(new Date());
        log.setDetails("批量删除部门，数量:" + ids.size());
        operationLogService.log(log);
        
        return R.ok();
    }
}